(function () {

    'use strict';


    /* =========================================================
       ЕНЛ — АККОРДЕОН СО СПИСКАМИ УРОКОВ
       ========================================================= */


    var SECTION_SELECTOR =
        '.enl-accordion-lessons-section';

    var TOGGLE_SELECTOR =
        '.enl-accordion-lessons-toggle';

    var CONTENT_SELECTOR =
        '.enl-accordion-lessons-content';

    var OPEN_CLASS =
        'enl-accordion-lessons-section--open';

    var LOCKED_CLASS =
        'enl-accordion-lessons-section--locked';

    var VISIBLE_CLASS =
        'enl-accordion-lessons-content--visible';

    var COMPLETE_CLASS =
        'enl-accordion-lesson-card--complete';



    /* =========================================================
       1. АККОРДЕОН
       ========================================================= */

    function initAccordion() {

        var sections =
            document.querySelectorAll(
                SECTION_SELECTOR
            );


        sections.forEach(
            function (section) {

                if (
                    section.dataset
                        .enlAccordionReady === '1'
                ) {
                    return;
                }


                /*
                 * Берём именно непосредственные элементы
                 * этой секции, чтобы случайная вложенность
                 * GetCourse не связывала разные аккордеоны.
                 */

                var toggle = null;
                var content = null;


                Array.prototype.forEach.call(
                    section.children,
                    function (child) {

                        if (
                            !toggle &&
                            child.matches &&
                            child.matches(
                                TOGGLE_SELECTOR
                            )
                        ) {
                            toggle = child;
                        }


                        if (
                            !content &&
                            child.matches &&
                            child.matches(
                                CONTENT_SELECTOR
                            )
                        ) {
                            content = child;
                        }

                    }
                );


                /*
                 * Если GC добавил техническую оболочку,
                 * оставляем запасной вариант поиска.
                 */

                if (!toggle) {

                    toggle =
                        section.querySelector(
                            TOGGLE_SELECTOR
                        );

                }


                if (!content) {

                    content =
                        section.querySelector(
                            CONTENT_SELECTOR
                        );

                }


                if (
                    !toggle ||
                    !content
                ) {
                    return;
                }


                section.dataset
                    .enlAccordionReady = '1';


                toggle.setAttribute(
                    'role',
                    'button'
                );

                toggle.setAttribute(
                    'tabindex',
                    '0'
                );


                function updateState() {

                    var locked =
                        section.classList.contains(
                            LOCKED_CLASS
                        );


                    var opened =
                        !locked &&
                        section.classList.contains(
                            OPEN_CLASS
                        );


                    toggle.setAttribute(
                        'aria-expanded',
                        opened
                            ? 'true'
                            : 'false'
                    );


                    toggle.setAttribute(
                        'aria-disabled',
                        locked
                            ? 'true'
                            : 'false'
                    );


                    content.classList.toggle(
                        VISIBLE_CLASS,
                        opened
                    );

                }


                function toggleAccordion() {

                    /*
                     * Заблокированный раздел
                     * никогда не раскрывается.
                     */

                    if (
                        section.classList.contains(
                            LOCKED_CLASS
                        )
                    ) {

                        section.classList.remove(
                            OPEN_CLASS
                        );

                        updateState();

                        return;
                    }


                    section.classList.toggle(
                        OPEN_CLASS
                    );


                    updateState();

                }


                toggle.addEventListener(
                    'click',
                    function (event) {

                        event.preventDefault();
                        event.stopPropagation();

                        toggleAccordion();

                    }
                );


                toggle.addEventListener(
                    'keydown',
                    function (event) {

                        if (
                            event.key !== 'Enter' &&
                            event.key !== ' '
                        ) {
                            return;
                        }


                        event.preventDefault();
                        event.stopPropagation();

                        toggleAccordion();

                    }
                );


                updateState();

            }
        );

    }



    /* =========================================================
       2. ОЧИСТКА НАЗВАНИЯ УРОКА
       ========================================================= */

    function cleanLessonTitle(
        source
    ) {

        var text =
            String(
                source || ''
            )
            .replace(
                /\s+/g,
                ' '
            )
            .trim();


        /*
         * В карточке нам нужно ТОЛЬКО название.
         *
         * «Просмотрено» для этой механики
         * вообще ничего не означает.
         *
         * Состояние выполнения задания
         * определяется отдельно по
         * user-state-accomplished.
         */

        text =
            text
            .replace(
                /\s+просмотрено\s*$/i,
                ''
            )
            .replace(
                /\s+не\s+просмотрено\s*$/i,
                ''
            )
            .replace(
                /\s+есть\s+задание\s*$/i,
                ''
            )
            .replace(
                /\s+задание\s+выполнено\s*$/i,
                ''
            )
            .replace(
                /\s+не\s+выполнено\s+важное\s+задание\s*$/i,
                ''
            )
            .trim();


        return text;
    }



    /* =========================================================
       3. ВЫПОЛНЕНО ЛИ ЗАДАНИЕ
       ========================================================= */

    function isLessonComplete(
        row
    ) {

        if (!row) {
            return false;
        }


        /*
         * Штатный статус GetCourse:
         *
         * user-state-accomplished
         * = ответ принят / урок выполнен.
         *
         * Другие состояния здесь намеренно
         * никак не отражаем.
         */


        if (
            row.classList &&
            row.classList.contains(
                'user-state-accomplished'
            )
        ) {
            return true;
        }


        if (
            row.querySelector &&
            row.querySelector(
                '.user-state-accomplished'
            )
        ) {
            return true;
        }


        return false;
    }



    /* =========================================================
       4. ПОИСК ОСНОВНОЙ ССЫЛКИ УРОКА
       ========================================================= */

    function findLessonLink(
        row
    ) {

        if (!row) {
            return null;
        }


        var links =
            Array.prototype.slice.call(
                row.querySelectorAll(
                    'a[href]'
                )
            );


        /*
         * Обычно самая содержательная ссылка
         * и является ссылкой на урок.
         */

        var candidates =
            links.filter(
                function (link) {

                    var text =
                        (
                            link.innerText ||
                            link.textContent ||
                            ''
                        )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim();


                    return (
                        text.length > 2
                    );

                }
            );


        if (!candidates.length) {
            return null;
        }


        candidates.sort(
            function (a, b) {

                var aText =
                    (
                        a.innerText ||
                        a.textContent ||
                        ''
                    ).length;


                var bText =
                    (
                        b.innerText ||
                        b.textContent ||
                        ''
                    ).length;


                return bText - aText;

            }
        );


        return candidates[0];
    }



    /* =========================================================
       5. ОФОРМЛЕНИЕ СПИСКОВ УРОКОВ
       ========================================================= */

    function decorateAccordionLessons() {

        var accordionContents =
            document.querySelectorAll(
                CONTENT_SELECTOR
            );


        accordionContents.forEach(
            function (content) {

                var lists =
                    content.querySelectorAll(
                        '.lesson-list, ' +
                        '.stream-table, ' +
                        '.training-list'
                    );


                lists.forEach(
                    function (list) {

                        list.classList.add(
                            'enl-accordion-lessons-grid'
                        );


                        /*
                         * В GetCourse список может быть
                         * таблицей или обычным списком.
                         */

                        var rows =
                            list.querySelectorAll(
                                'tr, li'
                            );


                        rows.forEach(
                            function (row) {

                                if (
                                    row.dataset
                                        .enlAccordionLessonReady === '1'
                                ) {
                                    return;
                                }


                                var link =
                                    findLessonLink(
                                        row
                                    );


                                if (!link) {
                                    return;
                                }


                                var rawTitle =
                                    (
                                        link.innerText ||
                                        link.textContent ||
                                        ''
                                    );


                                var title =
                                    cleanLessonTitle(
                                        rawTitle
                                    );


                                if (!title) {
                                    return;
                                }


                                /*
                                 * ВАЖНО:
                                 * состояние читаем ДО того,
                                 * как скрываем GC-разметку.
                                 */

                                var complete =
                                    isLessonComplete(
                                        row
                                    );


                                row.dataset
                                    .enlAccordionLessonReady =
                                    '1';


                                row.classList.add(
                                    'enl-accordion-lesson-row'
                                );


                                link.classList.add(
                                    'enl-accordion-lesson-card'
                                );


                                if (complete) {

                                    link.classList.add(
                                        COMPLETE_CLASS
                                    );

                                }


                                /* -------------------------
                                   Скрываем исходную начинку
                                   ссылки, но не удаляем её.
                                   ------------------------- */

                                Array.prototype.slice.call(
                                    link.children
                                ).forEach(
                                    function (child) {

                                        child.classList.add(
                                            'enl-accordion-lesson-gc-original'
                                        );

                                    }
                                );


                                /* -------------------------
                                   Наша карточка
                                   ------------------------- */

                                var visual =
                                    document.createElement(
                                        'span'
                                    );


                                visual.className =
                                    'enl-accordion-lesson-visual';


                                var titleNode =
                                    document.createElement(
                                        'span'
                                    );


                                titleNode.className =
                                    'enl-accordion-lesson-title';


                                titleNode.textContent =
                                    title;


                                var side =
                                    document.createElement(
                                        'span'
                                    );


                                side.className =
                                    'enl-accordion-lesson-side';


                                var arrow =
                                    document.createElement(
                                        'span'
                                    );


                                arrow.className =
                                    'enl-accordion-lesson-arrow';


                                arrow.setAttribute(
                                    'aria-hidden',
                                    'true'
                                );


                                arrow.textContent =
                                    '→';


                                side.appendChild(
                                    arrow
                                );


                                visual.appendChild(
                                    titleNode
                                );


                                visual.appendChild(
                                    side
                                );


                                link.appendChild(
                                    visual
                                );

                            }
                        );

                    }
                );

            }
        );

    }



    /* =========================================================
       6. ОБЩАЯ ИНИЦИАЛИЗАЦИЯ
       ========================================================= */

    function initEnlLessons() {

        initAccordion();

        decorateAccordionLessons();

    }



    if (
        document.readyState === 'loading'
    ) {

        document.addEventListener(
            'DOMContentLoaded',
            initEnlLessons
        );

    } else {

        initEnlLessons();

    }



    /*
     * GetCourse иногда достраивает блоки
     * уже после DOMContentLoaded.
     */

    window.addEventListener(
        'load',
        initEnlLessons
    );



    /*
     * Небольшая страховка для динамически
     * появившихся списков.
     */

    var observerTimer = null;


    var observer =
        new MutationObserver(
            function () {

                clearTimeout(
                    observerTimer
                );


                observerTimer =
                    setTimeout(
                        initEnlLessons,
                        100
                    );

            }
        );


    observer.observe(
        document.body,
        {
            childList: true,
            subtree: true
        }
    );

})();